
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="./cesium/Cesium1.98/Widgets/widgets.css" />
    <script type="text/javascript" src="./cesium/Cesium1.98/Cesium.js"></script>
    <script src="./latlng.js"></script>
    <script src="./cesium.map.min.js"></script>
    <script src="./../libs/dat-gui/0.7.6/dat.gui.min.js"></script>

</head>

<body style="
      margin: 0;
      overflow: hidden;
      background: #fff;
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
    ">
    <div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>

    <!-- ./video.mp4 -->
    <script type="text/javascript">
        Cesium.Ion.defaultAccessToken =
            "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ZjQ5ZGUzNC1jNWYwLTQ1ZTMtYmNjYS05YTY4ZTVmN2I2MDkiLCJpZCI6MTE3MTM4LCJpYXQiOjE2NzY0NDUyODB9.ZaNSBIfc1sGLhQd_xqhiSsc0yr8oS0wt1hAo9gbke6M";
        const viewer = new Cesium.Viewer("map", {
            // 添加这两行，就不会找烦人的defaultAccessToken了，也不会找在线底图了
            imageryProvider: false,
            baseLayerPicker: false,
        });
        viewer.scene.debugShowFramesPerSecond = true;
        viewer.scene.globe.depthTestAgainstTerrain = true;
        var options = {
            style: "img", // style: img、elec、cva
            crs: "WGS84", // 使用84坐标系，默认为：GCJ02
        };
        viewer.imageryLayers.add(
            new Cesium.ImageryLayer(new Cesium.AMapImageryProvider(options))
        );

        const gui = new dat.GUI();
        gui.domElement.style = 'position:absolute;top:10px;left:10px;'

        viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(120, 30, 20000),
        });
        let primitive, primitive1;
        const obj = {
            x: 120,
            y: 30,
            z: 2000,
            heading: 0,
            pitch: 180,
            roll: 0,
            fov: 30,
            near: 10,
            far: 3000,
            aspectRatio: 1.4,
        };


        var position = Cesium.Cartesian3.fromDegrees(obj.x, obj.y, obj.z);
        var heading = Cesium.Math.toRadians(obj.heading);
        var pitch = Cesium.Math.toRadians(obj.pitch);
        var roll = Cesium.Math.toRadians(obj.roll);

        var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
        var orientation = Cesium.Transforms.headingPitchRollQuaternion(
            position,
            hpr
        );


        gui.add(obj, 'x', -180, 180).name('经度').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'y', -90, 90).name('纬度').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'z', 100, 10000).name('高度').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'heading', 0, 360).name('偏航角-水平').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'pitch', 0, 360).name('俯仰角-上下').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'roll', 0, 360).name('翻滚角-侧向').onChange(function (value) {
            updateFrustum();
        });

        gui.add(obj, 'fov', 0, 180).name('上下角度').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'near', 0, 1000).name('近距').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'far', 0, 5000).name('远距').onChange(function (value) {
            updateFrustum();
        });
        gui.add(obj, 'aspectRatio', 0, 3).name('横向比例').onChange(function (value) {
            updateFrustum();
        });

        function updateFrustum() {
            viewer.scene.primitives.remove(primitive);
            viewer.scene.primitives.remove(primitive1);

            var position = Cesium.Cartesian3.fromDegrees(obj.x, obj.y, obj.z);
            var heading = Cesium.Math.toRadians(obj.heading);
            var pitch = Cesium.Math.toRadians(obj.pitch);
            var roll = Cesium.Math.toRadians(obj.roll);

            var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
            var orientation = Cesium.Transforms.headingPitchRollQuaternion(
                position,
                hpr
            );

            addFrustum(
                position,
                orientation,
                obj.fov,
                obj.near,
                obj.far,
                obj.aspectRatio
            );

        }


        // 绘制
        addFrustum(
            position,
            orientation,
            obj.fov,
            obj.near,
            obj.far,
            obj.aspectRatio
        );



        // 创建视锥体及轮廓线
        function addFrustum(position, orientation, fov, near, far, aspectRatio) {
            let frustum = new Cesium.PerspectiveFrustum({
                // 查看的视场角，绕Z轴旋转，以弧度方式输入
                fov: Cesium.Math.toRadians(fov),
                // 视锥体的宽度/高度
                aspectRatio: aspectRatio,
                // 近面距视点的距离
                near: near,
                // 远面距视点的距离
                far: far,
            });

            let instanceGeo = new Cesium.GeometryInstance({
                geometry: new Cesium.FrustumGeometry({
                    frustum: frustum,
                    origin: position,
                    orientation: orientation,
                    vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
                }),
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                        new Cesium.Color(1.0, 0.0, 0.0, 0.3)
                    ),
                },
            });
            let instanceGeoLine = new Cesium.GeometryInstance({
                geometry: new Cesium.FrustumOutlineGeometry({
                    frustum: frustum,
                    origin: position,
                    orientation: orientation,
                }),
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                        new Cesium.Color(1.0, 1.0, 1.0, 1)
                    ),
                },
            });


            primitive = new Cesium.Primitive({
                geometryInstances: [instanceGeo],
                appearance: new Cesium.PerInstanceColorAppearance({
                    closed: true,
                    flat: true,
                }),
                asynchronous: false,
            });

            primitive1 = new Cesium.Primitive({
                geometryInstances: [instanceGeoLine],
                appearance: new Cesium.PerInstanceColorAppearance({
                    closed: true,
                    flat: true,
                }),
                asynchronous: false,
            });
            viewer.scene.primitives.add(primitive);
            viewer.scene.primitives.add(primitive1);


            // --------------------------获取顶点坐标---------------------------------------------------------
            let zb = Cesium.FrustumOutlineGeometry.createGeometry(instanceGeo.geometry)
            const positions = zb.attributes.position.values;
            // console.log(positions)

            const temp = [];
            for (let i = 0; i < positions.length; i += 3) {
                temp.push(positions.slice(i, i + 3));
            }
            // console.log(temp)

            const result = [];
            temp.forEach(function (chunk) {
                result.push(latlng.formatPositon(new Cesium.Cartesian3(chunk[0], chunk[1], chunk[2])));
            });
            // console.log(result)
            // --------------------------获取顶点坐标---------------------------------------------------------


        }

    </script>
</body>

</html>